package org.csource.test;

import java.io.File;
import java.io.IOException;

import org.apache.log4j.Logger;
import org.csource.common.MyException;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.FileInfo;
import org.csource.fastdfs.ServerInfo;
import org.csource.fastdfs.StorageClient;
import org.csource.fastdfs.StorageClient1;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
import org.csource.fastdfs.test.TestLoad.DownloadFileDiscard;

/**
 * File Manager used to provide the services to upload / download / delete the
 * files from FastDFS.
 * 
 * <note>In this version, FileManager only support single tracker, will enhance
 * this later...</note>
 * 
 * @author Josh Wang(Sheng)
 *
 * @email josh_wang23@hotmail.com
 */
public class FileManager implements FileManagerConfig {

	private static final long serialVersionUID = 1L;

	private static Logger logger = Logger.getLogger(FileManager.class);

	private static TrackerClient trackerClient;
	private static TrackerServer trackerServer;
	private static StorageServer storageServer;
	private static StorageClient storageClient;
	private static StorageClient1 storageClient1;
	static { // Initialize Fast DFS Client configurations

		try {
			String classPath = new File(FileManager.class.getResource("/").getFile()).getPath();
			String fdfsClientConfigFilePath = classPath + File.separator + CLIENT_CONFIG_FILE;
			// fasedfs文件配置路劲.
			// String fdfsClientConfigFilePath =
			// "/home/leo/workspace2/ffmepg-decode-service/src/fdfs_client.conf";
			// String fdfsClientConfigFilePath = "D:/test/fdfs_client.conf";

			logger.info("Fast DFS configuration file path:" + fdfsClientConfigFilePath);
			ClientGlobal.init(fdfsClientConfigFilePath);

			trackerClient = new TrackerClient();
			trackerServer = trackerClient.getConnection();

			storageClient = new StorageClient(trackerServer, storageServer);
			storageClient1 = new StorageClient1(trackerServer, storageServer);
		} catch (Exception e) {
			logger.error(logger, e);

		}
	}

	public static String upload1(FastDFSFile file) {
		logger.info("File Name: " + file.getName());
		NameValuePair[] meta_list = new NameValuePair[3];
		meta_list[0] = new NameValuePair("width", "120");
		meta_list[1] = new NameValuePair("heigth", "120");
		meta_list[2] = new NameValuePair("author", "sys");
		long startTime = System.currentTimeMillis();
		String uploadResult = null;
		try {
			uploadResult = storageClient1.upload_file1(file.getName(), file.getExt(), meta_list);
		} catch (IOException e) {
			logger.error("IO Exception when uploadind the file: " + file.getName(), e);
			throw new RuntimeException(e);
		} catch (MyException e) {
			logger.error("Non IO Exception when uploadind the file: " + file.getName(), e);
			throw new RuntimeException(e);
		}
		logger.info("upload_file time used: " + (System.currentTimeMillis() - startTime) + " ms");
		if (uploadResult == null || "".equals(uploadResult)) {
			System.out.println(storageClient.getErrorCode());
			logger.error("upload file fail, error code: " + storageClient.getErrorCode());
			throw new RuntimeException("上传返回结果为空");
		}
		String fileAbsolutePath = PROTOCOL + INTERNET_IP + ":"
				+ TRACKER_NGNIX_PORT + SEPARATOR +uploadResult;
		logger.info("upload file successfully!!!  " + "http path:" +fileAbsolutePath);
		return fileAbsolutePath;
	}

	public static String upload(FastDFSFile file) {
		logger.info("File Name: " + file.getName() + "		File Length: " + file.getContent().length);

		NameValuePair[] meta_list = new NameValuePair[3];
		meta_list[0] = new NameValuePair("width", "120");
		meta_list[1] = new NameValuePair("heigth", "120");
		meta_list[2] = new NameValuePair("author", "Diandi");

		long startTime = System.currentTimeMillis();
		String[] uploadResults = null;
		try {
			uploadResults = storageClient.upload_file(file.getContent(), file.getExt(), meta_list);
		} catch (IOException e) {
			logger.error("IO Exception when uploadind the file: " + file.getName(), e);
			throw new RuntimeException(e);
		} catch (Exception e) {
			logger.error("Non IO Exception when uploadind the file: " + file.getName(), e);
			throw new RuntimeException(e);
		}
		logger.info("upload_file time used: " + (System.currentTimeMillis() - startTime) + " ms");

		if (uploadResults == null) {
			System.out.println(storageClient.getErrorCode());
			logger.error("upload file fail, error code: " + storageClient.getErrorCode());
			throw new RuntimeException("上传返回结果为空");
		}

		String groupName = uploadResults[0];
		String remoteFileName = uploadResults[1];
		
		String fileAbsolutePath = PROTOCOL + INTERNET_IP + ":"
				+ TRACKER_NGNIX_PORT + SEPARATOR + groupName + SEPARATOR + remoteFileName;
		
		logger.info("upload file successfully!!!  " + "group_name: " + groupName + ", remoteFileName:" + " "
				+ remoteFileName);

		return fileAbsolutePath;

	}

	public static FileInfo getFile(String groupName, String remoteFileName) {
		try {
			return storageClient.get_file_info(groupName, remoteFileName);
		} catch (IOException e) {
			logger.error("IO Exception: Get File from Fast DFS failed", e);
		} catch (Exception e) {
			logger.error("Non IO Exception: Get File from Fast DFS failed", e);
		}
		return null;
	}

	public static void deleteFile(String groupName, String remoteFileName) throws Exception {
		storageClient.delete_file(groupName, remoteFileName);
	}

	public static StorageServer[] getStoreStorages(String groupName) throws IOException {
		return trackerClient.getStoreStorages(trackerServer, groupName);
	}

	public static ServerInfo[] getFetchStorages(String groupName, String remoteFileName) throws IOException {
		return trackerClient.getFetchStorages(trackerServer, groupName, remoteFileName);
	}

	public static byte[] downloadFile(String groupName, String remoteFileName) throws IOException, MyException {
		return storageClient.download_file(groupName, remoteFileName);
	}
}